package com.flejay.dreamrecruiter.model;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Classe abstraite non instanciable qui représente un mot clef pour lequel on veut associer un bloc de données du CV ou un sous bloc
 * 
 * @author Victor Fleurant
 *
 */
public class AbstractTag {

	protected AbstractTag(){
		super();
	}
	
	public static AbstractTag getNewInstance(){
		AbstractTag tag = new AbstractTag();
		tag.setLabel("");
		tag.setRegexp(new ArrayList<Pattern>());
		return tag;
	}
	
	private String label;
	
	private List<Pattern> regexp;
	
	
	// pond�ration qui permet de calculer si un bloc est trop lourd
	private String sizeObjective;

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public String getSizeObjective() {
		return sizeObjective;
	}

	public void setSizeObjective(String sizeObjective) {
		this.sizeObjective = sizeObjective;
	}

	public List<Pattern> getRegexp() {
		return regexp;
	}

	public void setRegexp(List<Pattern> regexp) {
		this.regexp = regexp;
	}

	@Override
	public String toString(){
//		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
		return this.label;
	}
	
	@Override
	public Object clone() {
		AbstractTag clonedTag = getNewInstance();
		clonedTag.setLabel(this.getLabel());
		clonedTag.setSizeObjective(this.getSizeObjective());
		for (Pattern regex : this.getRegexp()){
			clonedTag.getRegexp().add(regex);
		}
		return clonedTag;
	}

	/**
	 * Cast a list of AbstractTag into a List of Tag
	 * @param aTagList
	 * @return
	 */
	public static List<Tag> toTagList(final List<AbstractTag> aTagList){
		List<Tag> tagRes = new ArrayList<Tag>();
		for(AbstractTag tag : aTagList){
			tagRes.add((Tag)tag);
		}
		return tagRes;
	}
	
	public static List<SubTag> toSubTagList(final List<AbstractTag> aTagList){
		List<SubTag> tagRes = new ArrayList<SubTag>();
		for(AbstractTag tag : aTagList){
			tagRes.add((SubTag)tag);
		}
		return tagRes;
	}
	
	/**
	 * Cast a list of Tag into a List of AbstractTag
	 * @param tagList
	 * @return
	 */
	public static List<AbstractTag> toAbstractTagList(final List<Tag> tagList){
		List<AbstractTag> tagRes = new ArrayList<AbstractTag>();
		for(Tag tag : tagList){
			tagRes.add((AbstractTag)tag);
		}
		return tagRes;
	}
	
	/**
	 * Cast a list of SubTag into a List of AbstractTag
	 * @param subTags
	 * @return
	 */
	public static List<AbstractTag> toAbstractTagListFromSubTags(List<SubTag> subTags) {
		List<AbstractTag> tagRes = new ArrayList<AbstractTag>();
		for(SubTag tag : subTags){
			tagRes.add((AbstractTag)tag);
		}
		return tagRes;
	}
	
	/**
	 * Retourne une nouvelle instance selon le type de l'objet passé en parametre
	 * @param tag
	 * @return
	 */
	public static AbstractBlock getNewInstanceTyped(AbstractTag tag) {
		AbstractBlock block = null;
		if (tag instanceof Tag){
			block = Block.getNewInstance();
		} else if(tag instanceof SubTag) {
			block = SubBlock.getNewInstance();
		} else {
			//error
			throw new IllegalStateException("First element of tag list is neither a Block or a SubBlock");
		}
		return block;
	}
}
